﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.DataAccess.Engine;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.Metadata.Entity;

namespace T.FAS.Runtime.DataAccess.Engine
{
    public class VirtualModelService
    {
        private const string Suffix = "_virt_dq";

        public static DataQuery GenerateVirtualDQ(DataObject doObj)
        {
            var suffix = "_virt_dq";

            var dq = new DataQuery
            {
                ID = doObj.ID + suffix,
                Code = doObj.Code + suffix,
                Name = doObj.Name + suffix,
                DataQuerySources = new List<DataQuerySource>
                {
                    new DataQuerySource
                    {
                        ID = doObj.ID + suffix,
						//DataQueryID = doObj.ID + suffix,
						Alias = doObj.Code,
                        SourceType = DataQuerySourceType.DataObject,
                        DataObjectID = doObj.ID,
                        DataObject = doObj,
                        IsMainSource = true,
                    }
                },
                DataQueryParams = new List<DataQueryParam>() { },
                DataQueryColumns = new List<DataQueryColumn> { },
                DataQueryFilters = new List<DataQueryFilter>() { },
                DataQuerySorts = new List<DataQuerySort>() { },
            };
            ProcessAdvancedQuery(dq);
            foreach (var col in doObj.Columns)
            {
                col.IsEnableColumnPermission = false;
                var dqCol = new DataQueryColumn
                {
                    ID = Guid.NewGuid().ToString(),
                    DataQuerySourceID = doObj.ID + suffix,
                    DataObjectID = doObj.ID,
                    DataObjectColumnID = col.ID,
                    Name = col.ColumnName,
                    Alias = col.ColumnName,              //DO生成的的DQ.Column列名不加DO.Code前缀
                    DisplayName = col.DisplayName,        //DQ主节点的列不加DO名
                    ColumnType = ColumnType.Normal,
                    ColumnDataType = col.ApplicationDataType,
                    IsHide = false,
                    DataColumn = col,
                    Sort = col.ColumnOrder,
                    DataQueryID = doObj.ID + suffix,
                };
                dq.DataQueryColumns.Add(dqCol);

                if (col.IsPkColumn)
                {
                    var pkSort = new DataQuerySort
                    {
                        ID = Guid.NewGuid().ToString(),
                        DataObjectID = doObj.ID,
                        DataObjectColumnID = col.ID,
                        SortColumnType = ColumnType.Normal,
                        Sort = 0,
                        SortItemType = 0,
                        SortType = 0,
                        DataQueryColumnID = dqCol.ID,
                    };
                    dq.DataQuerySorts.Add(pkSort);
                }
            }

            return dq;
        }

        public static DataQuery GenerateVirtualDQ(DataQuery dataQuery, List<GroupColumn> groupColumns)
        {
            var dq = dataQuery.Clone() as DataQuery;
            var pkCountCol = dataQuery.GetMainSourcePkColumn().Clone() as DataQueryColumn;
            pkCountCol.ID = Guid.NewGuid().ToString();
            pkCountCol.Alias = "Total";
            pkCountCol.ColumnType = ColumnType.Aggregate;
            pkCountCol.AggregateType = AggregateType.COUNT;
            dq.DataQueryColumns.Add(pkCountCol);

            foreach (var col in groupColumns)
            {
                var oriCol = QueryPlanFilterHelper.GetDataQueryColumnByFilterCode(col.Code, dataQuery);
                if (oriCol != null)
                {
                    var dqCol = oriCol.Clone() as DataQueryColumn;
                    dqCol.ID = Guid.NewGuid().ToString();
                    dqCol.ColumnType = ColumnType.Group;

                    dq.DataQueryColumns.Add(dqCol);
                }
            }

            return dq;
        }

        #region Private Funcs
        /// <summary>
        /// 处理高级查询的预置参数
        /// </summary>
        /// <param name="meta"></param>
        private static void ProcessAdvancedQuery(IMetaDataContent meta)
        {
            string advancedFilter = "AdvancedFilter";
            string advancedSort = "AdvancedSort";
            string pageIndex = "PageIndex";
            string pageSize = "PageSize";
            string extSetting = "ExtSetting";

            string advancedFilterCN = "高级查询过滤条件";
            string advancedSortCN = "高级查询排序条件";
            string pageIndexCN = "页码";
            string pageSizeCN = "分页大小";
            string extSettingCN = "扩展设置";

            DataQuery dq = meta as DataQuery;
            if (dq.DataQueryParams?.Count > 0)
            {
                for (int i = 0; i < dq.DataQueryParams.Count; i++)
                {
                    dq.DataQueryParams[i].Sort = i;
                }
            }
            ProcessParameter(meta, pageIndex, pageIndexCN, DataType.Int, 998);
            ProcessParameter(meta, pageSize, pageSizeCN, DataType.Int, 999);
            ProcessParameter(meta, advancedFilter, advancedFilterCN, DataType.String, 1000);
            ProcessParameter(meta, advancedSort, advancedSortCN, DataType.String, 1001);
            //只有当开启掩码设置时，增加扩展参数
            if (dq.IsEnableMask)
                ProcessParameter(meta, extSetting, extSettingCN, DataType.String, 1002);

            //处理高级查询过滤条件
            if (dq.DataQueryFilters.All(f => f.FilterExpression != $"@{advancedFilter}"))
            {
                //构建DQ默认条件，供高级查询的条件使用
                DataQueryFilter defaultFilter = new DataQueryFilter
                {
                    ID = Guid.NewGuid().ToString(),
                    DataQueryID = dq.ID,
                    FilterExpression = $"@{advancedFilter}",
                    FilterType = FilterType.Normal, //系统默认参数只支持普通条件
                    IsDefault = true,
                };
                dq.DataQueryFilters.Add(defaultFilter);
            }
        }

        /// <summary>
        /// 处理参数
        /// </summary>
        /// <param name="meta"></param>
        /// <param name="filterCode"></param>
        /// <param name="filterName"></param>
        /// <param name="dataType"></param>
        /// <param name="sort"></param>
        private static void ProcessParameter(IMetaDataContent meta, string filterCode, string filterName, DataType dataType, int sort)
        {
            DataQuery dq = meta as DataQuery;
            DataQueryParam AddParam;
            var defaultParam = dq.DataQueryParams.Where(f => f.Code == filterCode).ToList();
            if (defaultParam.Count == 0)
            {
                //构建默认入参
                AddParam = new DataQueryParam
                {
                    ID = Guid.NewGuid().ToString(),
                    DataQueryID = dq.ID,
                    Code = filterCode,
                    Name = filterName,
                    IsInputParam = true,
                    ParamType = dataType.ToString(),
                    IsAllowNull = true, //默认参数允许为空
                    IsDefault = true,
                    Sort = sort,
                };
                dq.DataQueryParams.Add(AddParam);
            }
            else if (defaultParam.Count > 1) //去重
            {
                AddParam = defaultParam[0];
                dq.DataQueryParams.RemoveAll(p => p.Code == filterCode);
                dq.DataQueryParams.Add(AddParam);
            }
            else
            {
                AddParam = defaultParam[0];
            }
        }

        #endregion
    }
}